package com.activenetwork.smlite.business;

import java.text.ParseException;
import java.util.Calendar;
import java.util.List;

import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.activenetwork.schema.model.event.EventBasicType;
import com.activenetwork.schema.model.event.EventType;
import com.activenetwork.schema.model.rfp.RfpAdditionalRequestType;
import com.activenetwork.schema.model.rfp.RfpType;
import com.activenetwork.schema.model.vendor.EPVendorSearchType;
import com.activenetwork.smlite.page.event.EventDetailView.EventSourceSubview;
import com.activenetwork.smlite.page.event.EventDetailView.EventSummarySubview;
import com.activenetwork.smlite.page.generic.NexusProgressPageObjectListener;
import com.activenetwork.smlite.page.rfp.RfpBasicsSubview;
import com.activenetwork.smlite.page.rfp.ViewRFPDetailTemplate;
import com.activenetwork.smlite.page.rfp.RfpMaintenanceView.RfpAdditionalRequest;
import com.activenetwork.smlite.page.rfp.RfpMaintenanceView.RfpEventSpace;
import com.activenetwork.smlite.page.rfp.RfpMaintenanceView.RfpFoodBeverage;
import com.activenetwork.smlite.page.rfp.RfpMaintenanceView.RfpReview;
import com.activenetwork.smlite.page.rfp.RfpMaintenanceView.RfpSetting;
import com.activenetwork.smlite.page.rfp.RfpMaintenanceView.RfpSleepingRoom;
import com.activenetwork.smlite.page.rfp.RfpMaintenanceView.RfpVendorSearch;
import com.activenetwork.smlite.snippet.RfpDateCalculator;
import com.activenetwork.util.DateUtil;
import com.activenetwork.util.EnvContext;
import com.activenetwork.util.PageLoader;
import com.activenetwork.util.WaitUtil;
import com.activenetwork.util.WindowLoader;

public class RfpBusiness {
	private Logger logger = LoggerFactory.getLogger(RfpBusiness.class);
	private EventBusiness eventBusiness;
	
	public RfpBusiness(){
		eventBusiness = new EventBusiness();
	}
	/**
	 * Search out the event, if not exist, throw RuntimeException
	 * Search the rfp by rfp data object
	 * @param event
	 * @param rfp
	 */
	public void searchRfp(EventType event, RfpType rfp){
		// Search out the event
		String eventName = event.getBasic().getTitle();
		eventBusiness.searchEvent(eventName, event);
		EventSummarySubview eventSummarySubview = PageLoader.load(EventSummarySubview.class);
		EventSourceSubview eventSourceSubview = eventSummarySubview.navigateSourcing();
		// Search out the rfp
		logger.debug("Click the specific rfp name link in the grid");
		eventSourceSubview.selectRfpFromGrid(rfp);
	}
	/**
	 * Search out the event, if not exist, throw RuntimeException
	 * Search the rfp by rfp name string
	 * @param event
	 * @param rfpName
	 */
	public void searchRfp(EventType event, String rfpName){
		// Search out the event
		String eventName = event.getBasic().getTitle();
		eventBusiness.searchEvent(eventName, event);
		EventSummarySubview eventSummarySubview = PageLoader.load(EventSummarySubview.class);
		EventSourceSubview eventSourceSubview = eventSummarySubview.navigateSourcing();
		// Search out the rfp
		logger.debug("Click the specific rfp name link in the grid");
		eventSourceSubview.selectRfpFromGrid(rfpName);
	}
	/**
	 * Search out the event by event name string, if not exist, throw RuntimeException
	 * Search the rfp by rfp data object
	 * @param eventName
	 * @param rfp
	 */
	public void searchRfp(String eventName, RfpType rfp){
		EventType event = new EventType();
		EventBasicType eventBasic = new EventBasicType();
		eventBasic.setTitle(eventName);
		searchRfp(event, rfp);
	}
	/**
	 * Search out the event by event name string, if not exist, throw RuntimeException
	 * Search the rfp by rfp name string
	 * @param eventName
	 * @param rfpName
	 */
	public void searchRfp(String eventName, String rfpName){
		EventType event = new EventType();
		EventBasicType eventBasic = new EventBasicType();
		eventBasic.setTitle(eventName);
		event.setBasic(eventBasic);
		searchRfp(event, rfpName);
	}
	/**
	 * Search out the event, if not exist, create a new event
	 * Create a new rfp based on this event
	 * @param event
	 * @param rfp
	 */
	public void createRfp(EventType event, RfpType rfp){
		// Search out the event
		try{
			String searchContent = event.getBasic().getTitle();
			eventBusiness.searchEvent(searchContent, event);
		}catch(RuntimeException e){ // event does not exist, create a new one
			logger.info("Unable to find the event, create a new one");
			// pay attention that event must have sourcing component is offered
			eventBusiness.addEvent(event);
			EventSourceSubview eventSourceSubview = PageLoader.load(EventSourceSubview.class);
			eventSourceSubview.showSummary();
		}
		
		EventSummarySubview eventSummarySubview = PageLoader.load(EventSummarySubview.class);
		eventSummarySubview.navigateSourcing();

		// Create rfp under this event
		create(rfp, RFPDEST.RFP);
	}
	/**
	 * Search out the event, if not exist, throw RuntimeException
	 * Create a new rfp based on this event if found
	 * @param event
	 * @param rfp
	 */
	public void createRfp(String eventName, RfpType rfp){
		// Search out the event
		eventBusiness.searchEvent(eventName, eventName);
		EventSummarySubview eventSummarySubview = PageLoader.load(EventSummarySubview.class);
		eventSummarySubview.navigateSourcing();
		
		// Create rfp under this event
		create(rfp, RFPDEST.RFP);
	}
	/**
	 * Search out the event, if not exist, create a new event
	 * Create a new rfp draft based on this event
	 * @param event
	 * @param rfp
	 */
	public void createRfpDraft(EventType event, RfpType rfp){
		// Search out the event
		try{
			String searchContent = event.getBasic().getTitle();
			eventBusiness.searchEvent(searchContent, event);
		}catch(RuntimeException e){ // event does not exist, create a new one
			logger.info("Unable to find the event, create a new one");
			// pay attention that event must have sourcing component is offered
			eventBusiness.addEvent(event);
			EventSourceSubview eventSourceSubview = PageLoader.load(EventSourceSubview.class);
			eventSourceSubview.showSummary();
		}
		
		EventSummarySubview eventSummarySubview = PageLoader.load(EventSummarySubview.class);
		eventSummarySubview.navigateSourcing();
		// Create rfp draft under this event
		create(rfp, RFPDEST.DRAFT);
	}
	/**
	 * Search out the event, if not exist, throw RuntimeException
	 * Create a new rfp draft based on this event if found
	 * @param event
	 * @param rfp
	 */
	public void createRfpDraft(String eventName, RfpType rfp){
		// Search out the event
		eventBusiness.searchEvent(eventName, eventName);
		EventSummarySubview eventSummarySubview = PageLoader.load(EventSummarySubview.class);
		eventSummarySubview.navigateSourcing();
		
		// Create rfp under this event
		create(rfp, RFPDEST.DRAFT);
	}
	/**
	 * Create rfp detail logic
	 * @param rfp
	 * @param rfpdest
	 * @throws ParseException 
	 */
	public void create(RfpType rfp, RFPDEST rfpdest){
		// Click Add Rfp
		logger.info("Click Add Rfp button");
		EventSourceSubview eventSourceSubview = PageLoader.load(EventSourceSubview.class);
		RfpSetting rfpSetting = eventSourceSubview.clickAddRfp();
		
		// Rfp Basics
		logger.info("Set Rfp Basics page");
		if(rfp.getBasic().getRfpName() != null){
			String rfpName = rfp.getBasic().getRfpName(); // + "-" + DateUtil.generateTimeStamp();
			rfpSetting = rfpSetting.setRfpName(rfpName);
		}
		if(rfp.getBasic().getDueDate() != null){
			rfpSetting = rfpSetting.setDueDate(DateUtil.toCalendar(rfp.getBasic().getDueDate()));
		}
		rfpSetting = rfpSetting.setEventNeeds(rfp.getBasic());
		rfpSetting = rfpSetting.setPrecedingShoulder(rfp.getBasic().getPrecedingShoulderDay());
		rfpSetting = rfpSetting.setFollowingShoulder(rfp.getBasic().getFollowingShoulderDay());
		
		// Get rfp start date and end date
		// Construct the rfp date model
		RfpDateCalculator calculator = null;
		try{
			Calendar rfpStartDateCal = rfpSetting.getRfpStartDate();
			Calendar rfpEndDateCal = rfpSetting.getRfpEndDate();
			
			DateUtil du = new DateUtil();
			
			String rfpStartDate = du.toString(rfpStartDateCal);
			String rfpEndDate = du.toString(rfpEndDateCal);
			calculator = new RfpDateCalculator(rfpStartDate, rfpEndDate, 
										rfp.getBasic().getPrecedingShoulderDay(), 
										rfp.getBasic().getFollowingShoulderDay());
		}catch(ParseException e){
			throw new RuntimeException("Unable to get rfp start & end date and unable to construct rfp date model");
		}
		
		RfpBasicsSubview nextPage = rfpSetting.clickNext();
		
	
		// Rfp Sleeping Room
		if(nextPage instanceof RfpSleepingRoom){
			logger.info("Set Rfp Sleeping Room page");
			RfpSleepingRoom rfpSleepingRoom = (RfpSleepingRoom)nextPage;
					
			// Setup the sleeping room days
			rfpSleepingRoom = rfpSleepingRoom.setPrecedingSleepingRoom(rfp.getSleepingRoomRequirement(), calculator);
			rfpSleepingRoom = rfpSleepingRoom.setOriginSleepingRoom(rfp.getSleepingRoomRequirement(), calculator);
			rfpSleepingRoom = rfpSleepingRoom.setFollowingSleepingRoom(rfp.getSleepingRoomRequirement(), calculator);
			// comment
			if(rfp.getSleepingRoomRequirement().getComment() != null){
				rfpSleepingRoom = rfpSleepingRoom.showAdditionalInformation();
				rfpSleepingRoom = rfpSleepingRoom.setComment(rfp.getSleepingRoomRequirement().getComment());
			}
			nextPage = rfpSleepingRoom.clickNext();
		}
		
		// Rfp Event Space
		if(nextPage instanceof RfpEventSpace){
			logger.info("Set Rfp Event Space page");
			RfpEventSpace rfpEventSpace = (RfpEventSpace)nextPage;
			// setup the event spaces
			rfpEventSpace = rfpEventSpace.setPrecedingShoulderEventSpace(rfp.getMeetingSpace(), calculator);
			rfpEventSpace = rfpEventSpace.setOriginEventSpace(rfp.getMeetingSpace(), calculator);
			rfpEventSpace = rfpEventSpace.setFollowingShoulderEventSpace(rfp.getMeetingSpace(), calculator);
			rfpEventSpace = rfpEventSpace.setCopyAllDayEventSpace(rfp.getMeetingSpace(), calculator);
			// comment
			if(rfp.getMeetingSpace().getComment() != null){
				rfpEventSpace = rfpEventSpace.showAdditionalInformation();
				rfpEventSpace = rfpEventSpace.setComment(rfp.getMeetingSpace().getComment());
			}
			nextPage = rfpEventSpace.clickNext();
		}
		
		// Rfp Food & Beverage
		if(nextPage instanceof RfpFoodBeverage){
			logger.info("Set Rfp Food & Beverage page");
			RfpFoodBeverage rfpFoodBeverage = (RfpFoodBeverage)nextPage;
			// setup the event food & beverage
			rfpFoodBeverage = rfpFoodBeverage.setPrecedingShoulderFoodBeverage(rfp.getFoodBeverage(), calculator);
			rfpFoodBeverage = rfpFoodBeverage.setOriginFoodBeverage(rfp.getFoodBeverage(), calculator);
			rfpFoodBeverage = rfpFoodBeverage.setFollowingShoulderFoodBeverage(rfp.getFoodBeverage(), calculator);
			rfpFoodBeverage = rfpFoodBeverage.setCopyAllDayFoodBeverage(rfp.getFoodBeverage(), calculator);
			// comment
			if(rfp.getFoodBeverage().getComment() != null){
				rfpFoodBeverage = rfpFoodBeverage.showAdditionalInformation();
				rfpFoodBeverage = rfpFoodBeverage.setComment(rfp.getFoodBeverage().getComment());
			}
			nextPage = rfpFoodBeverage.clickNext();
		}
		
		// Rfp Additional Request
		if(nextPage instanceof RfpAdditionalRequest){
			logger.info("Set Rfp Additional Request page");
			RfpAdditionalRequest rfpAdditionalRequest = (RfpAdditionalRequest)nextPage;
			// setup the event additional request
			rfpAdditionalRequest = rfpAdditionalRequest.setPrecedingShoulderAdditionalRequest(rfp.getAdditionalRequest(), calculator);
			rfpAdditionalRequest = rfpAdditionalRequest.setOriginAdditionalRequest(rfp.getAdditionalRequest(), calculator);
			rfpAdditionalRequest = rfpAdditionalRequest.setFollowingShoulderAdditionalRequest(rfp.getAdditionalRequest(), calculator);
			rfpAdditionalRequest = rfpAdditionalRequest.setCopyAllDayAdditionalRequest(rfp.getAdditionalRequest(), calculator);
			// comment
			if(rfp.getAdditionalRequest().getComment() != null){
				rfpAdditionalRequest = rfpAdditionalRequest.showAdditionalInformation();
				rfpAdditionalRequest = rfpAdditionalRequest.setComment(rfp.getAdditionalRequest().getComment());
			}
			// upload attachments
			List<RfpAdditionalRequestType.Attachments> attachments = rfp.getAdditionalRequest().getAttachments();
			for(RfpAdditionalRequestType.Attachments attachment : attachments){
				rfpAdditionalRequest = rfpAdditionalRequest.clickAddNewAttach();
				rfpAdditionalRequest = rfpAdditionalRequest.setAttachment(attachment.getFilepath(), attachment.getFiledesc());
				rfpAdditionalRequest = rfpAdditionalRequest.clickUploadAttachment();
			}
			
			nextPage = rfpAdditionalRequest.clickNext();
		}
		
		// Rfp Vendor Search
		if(nextPage instanceof RfpVendorSearch){
			// When opening the vendor search page, 
			// first time it will display nexus progress bar
			// After that, there will be no more nexus progress bar 
			// on vendor search page
			WaitUtil waitUtil = new WaitUtil();
			waitUtil.wait(5000);
						
			logger.info("driver switch frame");
			WebDriver driver = EnvContext.webDriverTL.get();
			driver.switchTo().frame("vendorSearchIframe");
			PageLoader.addException(NexusProgressPageObjectListener.class, RfpVendorSearch.class);
			
			logger.info("Set Rfp Vendor Search page");			
			// vendor business code
			VendorSearchBusiness vendorBusiness = new VendorSearchBusiness();
			// loop vendor list
			List<EPVendorSearchType> vendors = rfp.getVendorSearch().getVendors();
			for(EPVendorSearchType vendor : vendors){
				vendorBusiness.selectEPVendor(vendor);
			}
			// check if there is any vendor in chart
			RfpVendorSearch rfpVendorSearch = PageLoader.load(RfpVendorSearch.class);			
			nextPage = rfpVendorSearch.clickContinue();
			
			logger.info("driver set default content");
			driver.switchTo().defaultContent();
			PageLoader.removeException(NexusProgressPageObjectListener.class, RfpVendorSearch.class);
		}
		
		// Rfp Review
		if(nextPage instanceof RfpReview){
			logger.info("Set Rfp Review page");
			WebDriver driver = EnvContext.webDriverTL.get();
			RfpReview rfpReview = (RfpReview)nextPage;
			// Open view rfp detail page
			WindowLoader windowLoader = new WindowLoader(driver.getWindowHandle());
			ViewRFPDetailTemplate rfpDetail = rfpReview.viewRfpDetail(windowLoader);
			logger.info(rfpDetail.getPageHeader());
			rfpReview = rfpDetail.close(windowLoader);
			// Send Rfp or not
			if(rfpdest == RFPDEST.RFP){
				rfpReview.sendRfp();
			}else if(rfpdest == RFPDEST.DRAFT){
				rfpReview.clickCancel();
			}
		}
		
		logger.info("Rfp business done");
	}
	
	/**
	 * Search out the event by event data object
	 * Delete the rfp by rfp data object
	 * @param event
	 * @param rfp
	 */
	public void deleteRfp(EventType event, RfpType rfp){
		logger.debug("Search out the event");
		String eventName = event.getBasic().getTitle();
		eventBusiness.searchEvent(eventName, event);
		EventSummarySubview eventSummarySubview = PageLoader.load(EventSummarySubview.class);
		EventSourceSubview eventSourceSubview = eventSummarySubview.navigateSourcing();
		logger.debug("Click delete rfp");
		eventSourceSubview = eventSourceSubview.checkRfpFromGrid(rfp);
		eventSourceSubview = eventSourceSubview.clickDeleteRfp();
		logger.debug("Kill the pop up");
		eventSourceSubview.confirmPopup(true);
	}
	/**
	 * Search out the vent by event name
	 * Delete the rfp by rfp name
	 * @param eventName
	 * @param rfp
	 */
	public void deleteRfp(String eventName, RfpType rfp){
		EventType event = new EventType();
		EventBasicType eventBasic = new EventBasicType();
		eventBasic.setTitle(eventName);
		deleteRfp(event, rfp);
	}
	/**
	 * Search out the event by event data object
	 * Delete the rfp by rfp name
	 * @param event
	 * @param rfp
	 */
	public void deleteRfp(EventType event, String rfp){
		logger.debug("Search out the event");
		String eventName = event.getBasic().getTitle();
		eventBusiness.searchEvent(eventName, event);
		EventSummarySubview eventSummarySubview = PageLoader.load(EventSummarySubview.class);
		EventSourceSubview eventSourceSubview = eventSummarySubview.navigateSourcing();
		logger.debug("Click delete rfp");
		eventSourceSubview = eventSourceSubview.checkRfpFromGrid(rfp);
		eventSourceSubview = eventSourceSubview.clickDeleteRfp();
		logger.debug("Kill the pop up");
		eventSourceSubview.confirmPopup(true);
	}
	/**
	 * Search out the event by event name
	 * Delete the rfp by rfp name
	 * @param eventName
	 * @param rfp
	 */
	public void deleteRfp(String eventName, String rfp){
		EventType event = new EventType();
		EventBasicType eventBasic = new EventBasicType();
		eventBasic.setTitle(eventName);
		deleteRfp(event, rfp);
	}
	
	
}

enum RFPDEST{
	RFP,DRAFT
}
